<?php

class UsersModel extends Model
{
    const SALT = 'sdfklfdvflrlsq';
    
    protected $table = 'users';
    
    /**
     * Количество найденных элементов последним запросом
     *
     * @var int
     */
    protected $total_count = 0;
    
    /**
     * Получить пользователя по его id
     * @param $id
     * 
     * @return User
     */
    public function get($id)
    {
        $data = $this->getQueryConstructor()->findById($id)->fetch();
        
        if ($data) {
            return new User($data['id'], $data['email'], $data['password'], $data['status'], $data['hash'], $data['register_date'], $data['last_visit_date']);
        }
        return null;
    }
    
    /**
     * Добавить пользователя
     * @param $user
     * @param $password
     * @param $status
     * 
     * @return int
     */
    public function insert($email, $password, $status = self::STATUS_NEW)
    {
        $data = array(
            'email' => $email,
            'password' => $password,
            'status' => $status,
            'hash' => md5($email . self::SALT . $password . self::SALT),
        );
        
        $sql = 'INSERT INTO `'.$this->table.'` (`email`, `password`, `status`, `hash`, `register_date`) VALUES (s:email, MD5(s:password), i:status, s:hash, NOW())';
        $this->prepare($sql)->query($data);
        
        return $this->getLastInsertId();
    }
    
    /**
     * Обновляет данные о пользователе
     * @param User $user
     */
    public function update(User $user)
    {
        $data = array(
            'id' => $user->getId(),
            'email' => $user->getEmail(),
            'password' => $user->getPassword(),
            'status' => $user->getStatus(),
            'hash' => $user->getHash(),
            'register_date' => $user->getRegisterDate(),
            'last_visit_date' => $user->getLastVisitDate()
        );
        
        $sql = "UPDATE `$this->table` SET `email` = s:email, `password` = s:password, status = i:status, hash = s:hash, register_date = s:register_date, last_visit_date = s:last_visit_date WHERE id = i:id";
        return (bool)$this->prepare($sql)->exec($data);
    }
    
    /**
     * Удаляет пользователя
     * @param $id
     */
    public function delete($id)
    {
        return (bool)$this->prepare("DELETE FROM $this->table WHERE id = i:id")->exec(array('id' => $id));
    }
    
    /**
     * Обновить статус пользователя
     * @param User $user
     * 
     * @return bool
     */
    public function setStatus(User $user)
    {
        $sql = 'UPDATE `'.$this->table.'` SET `status` = i:new WHERE `id` = i:id';
        return(bool)$this->prepare($sql)->exec(array('id' => $user->getId(), 'new' => $user->getStatus()));
    }
    
    /**
     * Получить пользователя по хешу
     * @param $hash
     * 
     * @return User
     */
    public function getByHash($hash)
    {
        $data = $this->getQueryConstructor()->findById($hash, 'hash')->fetch();
        
        if ($data) {
            return new User($data['id'], $data['email'], $data['password'], $data['status'], $data['hash'], $data['register_date'], $data['last_visit_date']);
        }
        return null;
    }
    
    /**
     * Получает список пользователей
     * @param $page
     * @param $limit
     * @param $filters
     * @param $order
     */
    public function getList($page = 0, $limit = 30, $filters = array(), $order = array())
    {
        $offset = (intval($page) > 0 ? intval($page) - 1 : 0) * $limit;
        
        $c = $this->getQueryConstructor();
        
        foreach ((array)$filters as $field => $value) {
            $c->filter($field, $value);
        }
        
        $this->total_count = $c->count();
        
        if (!empty($order['field']) && !empty($order['by'])) {
            $c->order($order['field'], $order['by']);
        }
        
        $list_users = $c->limit($offset, $limit)->find()->fetchAll('id');

        $list = array();
        foreach ((array)$list_users as $id => $row) {
            $list[$id] = new User($row['id'],
                                  $row['email'],
                                  $row['password'],
                                  $row['status'],
                                  $row['hash'],
                                  $row['register_date'],
                                  $row['last_visit_date']);
        }
        
        return $list;
    }
    
    /**
     * @return int
     */
    public function getTotalCount()
    {
        return $this->total_count;
    }
    
    /**
     * Проверяет наличие e-maila в базе
     * @param $email
     */
    public function getIdByEmail($email)
    {
        return $this->getQueryConstructor()->filter('email', $email)->find()->fetchField('id');
    }
}